package socket.myRPC.proxy.impl;

import socket.myRPC.rpc.Dispatcher;
import socket.myRPC.rpc.protocol.MyContent;
import socket.myRPC.rpc.transport.ClientFactory;
import socket.myRPC.util.RequestTypeEnum;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.concurrent.CompletableFuture;

/**
 * 实现接口[InvocationHandler] 的实现类
 *
 * @author lihh
 */
public class InvocationHandlerImpl implements InvocationHandler {
  
  private final Class<?> interfaceInfo;
  
  public InvocationHandlerImpl(Class<?> interfaceInfo) {
    this.interfaceInfo = interfaceInfo;
  }
  
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // 表示 返回值
    Object res = null;
    // 通过 dispatcher 拿到对象，如果是 local 的服务的话，是会保存到 dispatcher的
    Object o = Dispatcher.get(interfaceInfo.getName());
    
    // 如果为 null 的话，表示 远程 remote
    if (o == null) {
      // 表示 远程执行 invoke
      RemoteInvoke remoteInvoke = new RemoteInvoke();
      remoteInvoke.injectionClassInfo(this.interfaceInfo);
      Object content = remoteInvoke.invoke(proxy, method, args);
      
      CompletableFuture<Object> completableFuture = ClientFactory.transport((MyContent) content, RequestTypeEnum.RPC);
      
      // 阻塞等待相应
      res = completableFuture.get();
    } else {
      // 表示 local 本地执行
      // 直接 通过 反射来执行 本地的方法
      LocalInvoke localInvoke = new LocalInvoke();
      localInvoke.injectionClassInfo(interfaceInfo);
      res = localInvoke.invoke(proxy, method, args);
    }
    return res;
  }
}
